﻿using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.tool.xml;
using iTextSharp.tool.xml.html;
using iTextSharp.tool.xml.parser;
using iTextSharp.tool.xml.pipeline.css;
using iTextSharp.tool.xml.pipeline.end;
using iTextSharp.tool.xml.pipeline.html;
using SupermarkedModel;
using System;
using System.IO;
using System.Linq;
using System.Text;

namespace Supermarket.Client
{
    internal static class PDFReportGenerator
    {
        public static void GenerateAggregatedSalesReport()
        {

            SupermarketDbEntities context = new SupermarketDbEntities();

            using (context)
            {
                int rowsCount = context.Reports.Count();

                if (rowsCount > 0)
                {
                    StringBuilder reportBuilder = new StringBuilder();
                    reportBuilder.Append("<table style='border-collapse:collapse' border='1' cellpadding='7'>");
                    reportBuilder.Append("<tr>");
                    reportBuilder.Append("<th colspan='5'>Agregate Sales Report</th>");
                    reportBuilder.Append("</tr>");

                    string headerRow = @"<tr>
                                    <th style='background-color:#cccccc; text-align:center'>Product</th>
                                    <th style='background-color:#cccccc; text-align:center'>Quantity</th>
                                    <th style='background-color:#cccccc; text-align:center'>Unit Price</th>
                                    <th style='background-color:#cccccc; text-align:center'>Location</th>
                                    <th style='background-color:#cccccc; text-align:center'>Sum</th>
                                </tr>";

                    var repotDates = context.Reports.GroupBy(x => x.Date).ToList();
                    decimal totalSum = 0m;

                    foreach (var date in repotDates)
                    {
                        DateTime currentDate = date.First().Date;
                        string currentDateAsString = currentDate.ToShortDateString().Substring(0, currentDate.ToShortDateString().Length - 2);
                        var currentDateReports = context.Reports.Where(r => r.Date == currentDate)
                            .Select(x => new
                            {
                                Quantity = x.Quantity,
                                UnitPrice = x.UnitPrice,
                                Supermarket = x.Supermarket.SupermarketName,
                                ProductID = x.ProductID,
                                Sum = x.Sum
                            }).ToList();

                        reportBuilder.Append("<tr>");
                        reportBuilder.Append("<td style='background-color:#cccccc' colspan='5'>Date: " +
                            currentDateAsString + "</td>");
                        reportBuilder.Append("</tr>");
                        reportBuilder.Append(headerRow);
                        var sum = 0m;

                        foreach (var report in currentDateReports)
                        {
                            reportBuilder.Append("<tr>");

                            reportBuilder.Append("<td>");
                            reportBuilder.Append(context.Products.Where(p => p.ID == report.ProductID)
                            .Select(n => n.ProductName).First());
                            reportBuilder.Append("</td>");

                            reportBuilder.Append("<td style='text-align:right'>");
                            reportBuilder.Append(Math.Round(report.Quantity, 3) + " " +
                                context.Products.Single(x => x.ID == report.ProductID).Measure.MeasureName);
                            reportBuilder.Append("</td>");

                            reportBuilder.Append("<td style='text-align:right'>");
                            reportBuilder.Append(Math.Round(report.UnitPrice, 2));
                            reportBuilder.Append("</td>");

                            reportBuilder.Append("<td>");
                            reportBuilder.Append(report.Supermarket);
                            reportBuilder.Append("</td>");

                            reportBuilder.Append("<td style='text-align:right'>");
                            reportBuilder.Append(Math.Round(report.Sum, 2));
                            reportBuilder.Append("</td>");
                            sum += report.Sum;
                            reportBuilder.Append("</tr>");
                        }

                        reportBuilder.Append("<tr>");
                        reportBuilder.Append("<td colspan='4'>Total sum for " + currentDateAsString + ":</td>");
                        reportBuilder.Append("<td>" + Math.Round(sum, 2) + "</td>");
                        reportBuilder.Append("</tr>");

                        reportBuilder.Append("<tr>");
                        reportBuilder.Append("<td colspan='5' height='20'></td>");
                        reportBuilder.Append("</tr>");

                        totalSum += sum;
                    }

                    reportBuilder.Append("<tr>");
                    reportBuilder.Append("<td colspan='4'>Grand total:</td>");
                    reportBuilder.Append("<td>" + Math.Round(totalSum, 2) + "</td>");
                    reportBuilder.Append("</tr>");
                    reportBuilder.Append("</table>");

                    GeneratePdf(reportBuilder);
                }
            }
        }

        private static void GeneratePdf(StringBuilder sb)
        {
            using (Document document = new Document())
            {
                DateTime today = DateTime.Now;
                var filePath = string.Format("../../Aggregated Sales Reports/as-of-{0}-{1}-{2}.pdf", today.Day, today.Month, today.Year);
                var fileStream = new FileStream(filePath, FileMode.Append);
                PdfWriter writer = PdfWriter.GetInstance(document, fileStream);
                document.Open();

                HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
                htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory());
                ICSSResolver cssResolver =
                    XMLWorkerHelper.GetInstance().GetDefaultCssResolver(false);
                IPipeline pipeline =
                    new CssResolverPipeline(cssResolver,
                        new HtmlPipeline(htmlContext,
                            new PdfWriterPipeline(document, writer)));
                XMLWorker worker = new XMLWorker(pipeline, true);
                var stream = sb.ToString();
                var stringReader = new StringReader(stream);
                XMLParser p = new XMLParser(worker);
                p.Parse(stringReader);
            }
        }
    }
}
